package vip.liux.contracts.security.core.extensions;

import lombok.Getter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 表示身份验证操作的结果。
 */
public class IdentityResult {
    /**
     * 表示成功的身份验证结果。
     */
    private static final IdentityResult SUCCESS = new IdentityResult(true, new ArrayList<>());

    /**
     * 是否操作成功。
     */
    @Getter
    private final boolean succeeded;

    /**
     * 操作中发生的错误列表。
     */
    private final List<IdentityError> errors;

    /**
     * 私有构造函数，用于创建身份验证结果。
     *
     * @param succeeded 是否成功
     * @param errors    错误列表
     */
    private IdentityResult(boolean succeeded, List<IdentityError> errors) {
        this.succeeded = succeeded;
        this.errors = errors != null ? errors : new ArrayList<>();
    }

    /**
     * 返回一个成功的身份验证结果。
     *
     * @return 成功的身份验证结果
     */
    public static IdentityResult success() {
        return SUCCESS;
    }

    /**
     * 返回一个失败的身份验证结果。
     *
     * @param errors 错误数组
     * @return 失败的身份验证结果
     */
    public static IdentityResult failed(IdentityError... errors) {
        List<IdentityError> errorList = new ArrayList<>();
        if (errors != null) {
            Collections.addAll(errorList, errors);
        }
        return new IdentityResult(false, errorList);
    }

    /**
     * 返回一个失败的身份验证结果。
     *
     * @param errors 错误列表
     * @return 失败的身份验证结果
     */
    public static IdentityResult failed(List<IdentityError> errors) {
        return new IdentityResult(false, errors);
    }

    /**
     * 获取错误列表。
     *
     * @return 不可修改的错误列表
     */
    public List<IdentityError> getErrors() {
        return Collections.unmodifiableList(errors);
    }

    /**
     * 返回表示当前对象的字符串。
     *
     * @return 对象的字符串表示
     */
    @Override
    public String toString() {
        if (succeeded) {
            return "Succeeded";
        } else {
            String codes = errors.stream()
                    .map(IdentityError::code)
                    .reduce((a, b) -> a + "," + b)
                    .orElse("");
            return "Failed : " + codes;
        }
    }
}